package com.gome.ss.monitor.data;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.log4j.Logger;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooKeeper;

import ProcessRouter.MessageStruct.ManagerInfoStruct;

import com.gome.ss.common.Utils;
import com.gome.ss.flowcrawl.plugin.FlowCrawlSpiderCommon;
import com.gome.ss.monitor.model.GroupItem;
import com.gome.ss.monitor.model.GroupSummary;
import com.gome.ss.monitor.model.NodeItem;
import com.google.protobuf.InvalidProtocolBufferException;

public class SpiderkitInfoConnection implements Watcher {
	private static Logger logger = Logger.getLogger(SpiderkitInfoConnection.class);
	
	private GroupSummary groupSummary = null;
	private boolean isConnected = false;
	String rootPath = "/spider_v2";
	
    private static final int SESSION_TIME   = 2000;
    protected ZooKeeper zooKeeper;
    protected CountDownLatch countDownLatch=new CountDownLatch(1);

    public boolean isConnected() {
		return isConnected;
	}

	public void setConnected(boolean isConnected) {
		this.isConnected = isConnected;
	}

	public void connect(String zkhost) throws IOException, InterruptedException, TimeoutException{
		try {
			zooKeeper = new ZooKeeper(zkhost,SESSION_TIME,(Watcher) this);
		} catch (IOException e) {
			isConnected = false;
			throw e;
		}

		try {
			TimeUnit unit = TimeUnit.SECONDS;
			if (countDownLatch.await(30, unit) == false) {
				isConnected = false;
				zooKeeper.close();
				throw new TimeoutException();
			}
		} catch (InterruptedException e) {
			isConnected = false;
			throw e;
		} catch (TimeoutException e) {
			isConnected = false;
			throw e;
		}
		
		this.groupSummary = new GroupSummary(zkhost);
		isConnected = true;
     }
    
	public void close() {
	    try {
	    	if (isConnected == true)
	    		zooKeeper.close();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			logger.error(Utils.getTrace(e));
		} finally {
			isConnected = false;
		}
	}

	@Override
	public void process(WatchedEvent event) {
		// TODO Auto-generated method stub
        if(event.getState()==KeeperState.SyncConnected) {
            countDownLatch.countDown();
        }
	}
	
	public void deleteNullGroup(String gname) {
		String path = this.rootPath + "/" + gname;
		try {
			if (this.zooKeeper.exists(path, false) != null) {
				List<String> mlist = this.zooKeeper.getChildren(path, false);
				for (String child : mlist) {
					String dpath = path + "/" + child;
					this.zooKeeper.delete(dpath, 0);
				}
				this.zooKeeper.delete(path, 0);
			}
		} catch (Exception e) {
			logger.error(Utils.getTrace(e));
		}
	}
	
	public void updateFromServer () throws KeeperException, InterruptedException, InvalidProtocolBufferException
	{
		List<GroupItem> groupList = new ArrayList<GroupItem>();
		
		List<String> root = this.zooKeeper.getChildren(rootPath, false);
		int nullGroupSize = 0;
		for (String g : root) {
			
			String mpath = rootPath + "/" + g;
			List<String> mlist = this.zooKeeper.getChildren(mpath, false);
			GroupItem gitem = new GroupItem();
			
			gitem.setGroupName(g);
			
			int nodeSize = 0;
			int totalPageCount = 0;
			int coreSize = 0;
			for (String m : mlist) {
				String dpath = mpath + "/" + m + "/stateinfo";
				if (this.zooKeeper.exists(dpath, false) == null)
					continue;
			
				byte[] data = this.zooKeeper.getData(dpath, false, null);
				ManagerInfoStruct info = ManagerInfoStruct.parseFrom(data);

				NodeItem item = new NodeItem(m, info);
				gitem.getNodeItemList().add(item);
				
				totalPageCount += info.getScurrentpc() + info.getDcurrentpc();
				coreSize += info.getCoresize();
				nodeSize ++;
			}
			
			gitem.setNodeSize(nodeSize);
			gitem.setTotalPageCount(totalPageCount);
			gitem.setCoreSize(coreSize);
			if (coreSize == 0)
				nullGroupSize ++;
			
			groupList.add(gitem);
		}
		
		this.groupSummary.setGroupList(groupList);
		this.groupSummary.setNullGroupSize(nullGroupSize);
	}

	public GroupSummary getGroupSummary() {
		return groupSummary;
	}

	public void setGroupSummary(GroupSummary groupSummary) {
		this.groupSummary = groupSummary;
	}
}
